package com.leetcode.algorithm.y19.m01;

import java.util.HashSet;
import java.util.Set;

/**
 * leetcode-cn.com
 * (done)771. 宝石与石头
 * (done)929. 独特的电子邮件地址
 * (done)709. 转换成小写字母
 * (done)905. 按奇偶排序数组
 * (done)961. 重复 N 次的元素
 * @author: jie.deng
 * @time: 2019年1月21日 上午11:02:34
 */
public class MySolution0121 {
	
	/**
	 * 771. 宝石与石头
	 * 
	 * 给定字符串J 代表石头中宝石的类型，和字符串 S代表你拥有的石头。 S 中每个字符代表了一种你拥有的石头的类型，你想知道你拥有的石头中有多少是宝石。
	 * 
	 * J 中的字母不重复，J 和 S中的所有字符都是字母。字母区分大小写，因此"a"和"A"是不同类型的石头。
	 * 
	 * 示例 1:
	 * 
	 * 输入: J = "aA", S = "aAAbbbb"
	 * 输出: 3
	 * 示例 2:
	 * 
	 * 输入: J = "z", S = "ZZ"
	 * 输出: 0
	 * 注意:
	 * 
	 * S 和 J 最多含有50个字母。
	 *  J 中的字符不重复。
	 * @param J
	 * @param S
	 * @return
	 */
	public int numJewelsInStones(String J, String S) {
		if (S == null || J == null) {
			return 0;
		}
		char[] sArr = S.toCharArray();
		int count = 0;
		for (char c : sArr) {
			if (J.indexOf(c) > -1) {
				count++;
			}
		}
		return count;
	}
    
    /**
     * 929. 独特的电子邮件地址
     * 
	 * 每封电子邮件都由一个本地名称和一个域名组成，以 @ 符号分隔。
	 * 
	 * 例如，在 alice@leetcode.com中， alice 是本地名称，而 leetcode.com 是域名。
	 * 
	 * 除了小写字母，这些电子邮件还可能包含 ',' 或 '+'。
	 * 
	 * 如果在电子邮件地址的本地名称部分中的某些字符之间添加句点（'.'），则发往那里的邮件将会转发到本地名称中没有点的同一地址。例如，"alice.z@leetcode.com” 和 “alicez@leetcode.com” 会转发到同一电子邮件地址。 （请注意，此规则不适用于域名。）
	 * 
	 * 如果在本地名称中添加加号（'+'），则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件，例如 m.y+name@email.com 将转发到 my@email.com。 （同样，此规则不适用于域名。）
	 * 
	 * 可以同时使用这两个规则。
	 * 
	 * 给定电子邮件列表 emails，我们会向列表中的每个地址发送一封电子邮件。实际收到邮件的不同地址有多少？
	 * 
	 *  
	 * 
	 * 示例：
	 * 
	 * 输入：["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
	 * 输出：2
	 * 解释：实际收到邮件的是 "testemail@leetcode.com" 和 "testemail@lee.tcode.com"。
	 *  
	 * 
	 * 提示：
	 * 
	 * 1 <= emails[i].length <= 100
	 * 1 <= emails.length <= 100
	 * 每封 emails[i] 都包含有且仅有一个 '@' 字符。
     * @param emails
     * @return
     */
	public int numUniqueEmails(String[] emails) {
		if (emails == null || emails.length == 0) {
			return 0;
		}
		Set<String> set = new HashSet<String>();
		for (String email : emails) {
			StringBuffer sbStr = new StringBuffer();
			int idx = email.indexOf('@');
			String local = email.substring(0, idx);
			local = email.substring(0, local.indexOf('+'));
			for (int i = 0; i < local.length(); i++) {
				if (local.charAt(i) != '.') {
					sbStr.append(local.charAt(i));
				}
			}
			sbStr.append(email.substring(idx));
			set.add(sbStr.toString());
		}
		return set.size();
	}
    
	/**
	 * 709. 转换成小写字母
	 * 
	 * 实现函数 ToLowerCase()，该函数接收一个字符串参数 str，并将该字符串中的大写字母转换成小写字母，之后返回新的字符串。
	 * 
	 *  
	 * 
	 * 示例 1：
	 * 
	 * 输入: "Hello"
	 * 输出: "hello"
	 * 示例 2：
	 * 
	 * 输入: "here"
	 * 输出: "here"
	 * 示例 3：
	 * 
	 * 输入: "LOVELY"
	 * 输出: "lovely"
	 * @param str
	 * @return
	 */
	public String toLowerCase(String str) {
		if (str == null) {
			return null;
		}
		StringBuffer sbStr = new StringBuffer();

		char[] charArr = str.toCharArray();
		int diff = 'a' - 'A';
		for (int i = 0; i < charArr.length; i++) {
			char ch = charArr[i];
			if (ch >= 'A' && ch <= 'Z') {
				sbStr.append((char)(ch + diff));
			} else {
				sbStr.append(ch);
			}
		}

		return sbStr.toString();
	}
	
    /**
     * 905. 按奇偶排序数组
     * 
	 * 给定一个非负整数数组 A，返回一个由 A 的所有偶数元素组成的数组，后面跟 A 的所有奇数元素。
	 * 
	 * 你可以返回满足此条件的任何数组作为答案。
	 * 
	 *  
	 * 
	 * 示例：
	 * 
	 * 输入：[3,1,2,4]
	 * 输出：[2,4,3,1]
	 * 输出 [4,2,3,1]，[2,4,1,3] 和 [4,2,1,3] 也会被接受。
	 *  
	 * 
	 * 提示：
	 * 
	 * 1 <= A.length <= 5000
	 * 0 <= A[i] <= 5000
     * @param A
     * @return
     */
    public int[] sortArrayByParity(int[] A) {
		if (A == null) {
			return null;
		}
		int len = A.length;
		int[] odd = new int[len]; // 奇数
		int[] even = new int[len];// 偶数
		int oddIdx = 0, evenInx = 0;
		for (int i = 0; i < len; i++) {
			if (A[i] % 2 == 0) {
				even[evenInx] = A[i];
				evenInx++;
			} else {
				odd[oddIdx] = A[i];
				oddIdx++;
			}
		}
		for (int i = 0; i < oddIdx; i++) {
			even[evenInx] = odd[i];
			evenInx++;
		}
		return even;
    }
    
    /**
     * 961. 重复 N 次的元素
     * 
	 * 在大小为 2N 的数组 A 中有 N+1 个不同的元素，其中有一个元素重复了 N 次。
	 * 
	 * 返回重复了 N 次的那个元素。
	 * 
	 *  
	 * 
	 * 示例 1：
	 * 
	 * 输入：[1,2,3,3]
	 * 输出：3
	 * 示例 2：
	 * 
	 * 输入：[2,1,2,5,3,2]
	 * 输出：2
	 * 示例 3：
	 * 
	 * 输入：[5,1,5,2,5,3,5,4]
	 * 输出：5
	 *  
	 * 
	 * 提示：
	 * 
	 * 4 <= A.length <= 10000
	 * 0 <= A[i] < 10000
	 * A.length 为偶数
     * @param A
     * @return
     */
	public int repeatedNTimes(int[] A) {
		int len = A.length;
		int[] b = new int[1 + len / 2];
		int idx = 0;
		for (int i = 0; i < len; i++) {
			for (int j = 0; j < idx; j++) {
				if (A[i] == b[j]) {
					return A[i];
				}
			}
			b[idx] = A[i];
			idx++;
		}
		return 0;
	}
}
